package org.tamal.controller;

import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.Cookie;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.MatrixVariable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * This is a demo controller.
 * @author Tamal Kanti Nath
 */
@Controller
public final class DemoController {

    private static final String USER_MAP = "userMap";
    private final String view = "demo";
    private Map<String, Integer> userMap = new TreeMap<>();

    /**
     * This method returns all the users visited this page.
     * @param model the model
     * @return the view name
     */
    @RequestMapping("/user")
    public String listUsers(Model model) {
        model.addAttribute(USER_MAP, userMap);
        return view;
    }

    /**
     * This method adds a user who has visited this page.
     * @param user the user
     * @param remove whether the user should be removed
     * @param model the model
     * @return the view name
     */
    @RequestMapping("/user/{user}")
    public String addUser(Model model, @PathVariable String user,
            @MatrixVariable(required = false) boolean remove) {
        if (remove) {
            userMap.remove(user);
            model.addAttribute(USER_MAP, userMap);
            return "redirect:../user";
        }
        Integer count = userMap.get(user);
        if (count == null) {
            count = 0;
        }
        userMap.put(user, ++count);
        model.addAttribute("user", user);
        model.addAttribute("count", count);
        return view;
    }

    /**
     * This method returns the locale.
     * @param model the model
     * @param locale locale
     * @param cookie the cookie
     * @return the view name
     */
    @RequestMapping("/locale")
    public String showHeaders(Model model, Locale locale,
            @CookieValue("JSESSIONID") Cookie cookie) {
        model.addAttribute("JSESSIONID", cookie.getValue());
        model.addAttribute(locale);
        return view;
    }

    /**
     * This method returns all the headers.
     * @param headers the headers
     * @param model the model
     * @return the view name
     */
    @RequestMapping("/header")
    public String showHeaders(Model model,
            @RequestHeader Map<String, String> headers) {
        model.addAttribute("headers", headers);
        return view;
    }

    /**
     * Gets the request body.
     * @param model the model
     * @return view name
     */
    @RequestMapping("/request")
    public String getRequest(Model model) {
        model.addAttribute("request", view);
        return view;
    }

    /**
     * Sets the response body.
     * @param body the request body
     * @return view name
     */
    @ResponseBody
    @RequestMapping(value = "/response", method = RequestMethod.POST)
    public static String setResponse(@RequestBody String body) {
        return body;
    }
}
